package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.pojo.dto.AuthorCreateDTO;
import com.zenithmind.library.pojo.dto.AuthorUpdateDTO;
import com.zenithmind.library.pojo.query.AuthorQuery;
import com.zenithmind.library.pojo.vo.AuthorVO;
import com.zenithmind.library.service.AuthorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 作者管理控制器
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/v1/authors")
@RequiredArgsConstructor
@Tag(name = "作者管理", description = "作者信息的增删改查操作")
public class AuthorController {

    private final AuthorService authorService;

    @GetMapping
    @Operation(summary = "分页查询作者", description = "根据条件分页查询作者列表")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<PageResult<AuthorVO>> getAuthorPage(@Valid AuthorQuery query) {
        log.info("分页查询作者，查询条件：{}", query);
        PageResult<AuthorVO> result = authorService.getAuthorPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询作者详情", description = "根据ID查询作者详细信息")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<AuthorVO> getAuthorDetail(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("查询作者详情，ID：{}", id);
        AuthorVO result = authorService.getAuthorDetail(id);
        return Result.success(result);
    }

    @PostMapping
    @Operation(summary = "创建作者", description = "新增作者信息")
    @PreAuthorize("hasAuthority('library:author:create')")
    public Result<AuthorVO> createAuthor(@Valid @RequestBody AuthorCreateDTO createDTO) {
        log.info("创建作者，数据：{}", createDTO);
        return authorService.createAuthor(createDTO);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新作者", description = "更新作者信息")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<AuthorVO> updateAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String id,
            @Valid @RequestBody AuthorUpdateDTO updateDTO) {
        log.info("更新作者，ID：{}，数据：{}", id, updateDTO);
        return authorService.updateAuthor(id, updateDTO);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除作者", description = "根据ID删除作者")
    @PreAuthorize("hasAuthority('library:author:delete')")
    public Result<Void> deleteAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("删除作者，ID：{}", id);
        return authorService.deleteAuthor(id);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除作者", description = "根据ID列表批量删除作者")
    @PreAuthorize("hasAuthority('library:author:delete')")
    public Result<Void> batchDeleteAuthors(@RequestBody List<String> ids) {
        log.info("批量删除作者，IDs：{}", ids);
        return authorService.batchDeleteAuthors(ids);
    }

    @PutMapping("/{id}/enable")
    @Operation(summary = "启用作者", description = "将作者设置为启用状态")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> enableAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("启用作者，ID：{}", id);
        return authorService.enableAuthor(id);
    }

    @PutMapping("/{id}/disable")
    @Operation(summary = "禁用作者", description = "将作者设置为禁用状态")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> disableAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("禁用作者，ID：{}", id);
        return authorService.disableAuthor(id);
    }

    @GetMapping("/name/{name}")
    @Operation(summary = "根据姓名查询作者", description = "根据作者姓名查询作者信息")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<List<AuthorVO>> getAuthorsByName(
            @Parameter(description = "作者姓名", required = true) @PathVariable String name) {
        log.info("根据姓名查询作者，姓名：{}", name);
        List<AuthorVO> result = authorService.getAuthorsByName(name);
        return Result.success(result);
    }

    @GetMapping("/book/{bookId}")
    @Operation(summary = "根据图书查询作者", description = "根据图书ID查询作者列表")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<List<AuthorVO>> getAuthorsByBookId(
            @Parameter(description = "图书ID", required = true) @PathVariable String bookId) {
        log.info("根据图书查询作者，图书ID：{}", bookId);
        List<AuthorVO> result = authorService.getAuthorsByBookId(bookId);
        return Result.success(result);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索作者", description = "根据关键词搜索作者")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<List<AuthorVO>> searchAuthors(
            @Parameter(description = "搜索关键词", required = true) @RequestParam String keyword,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("搜索作者，关键词：{}，限制数量：{}", keyword, limit);
        List<AuthorVO> result = authorService.searchAuthors(keyword, limit);
        return Result.success(result);
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门作者", description = "获取热门作者列表")
    public Result<List<AuthorVO>> getHotAuthors(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("获取热门作者，限制数量：{}", limit);
        List<AuthorVO> result = authorService.getHotAuthors(limit);
        return Result.success(result);
    }

    @GetMapping("/productive")
    @Operation(summary = "获取高产作者", description = "获取高产作者列表")
    public Result<List<AuthorVO>> getProductiveAuthors(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("获取高产作者，限制数量：{}", limit);
        List<AuthorVO> result = authorService.getProductiveAuthors(limit);
        return Result.success(result);
    }

    @PutMapping("/{id}/book-count")
    @Operation(summary = "更新作者作品数量", description = "重新统计并更新作者的作品数量")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> updateAuthorBookCount(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("更新作者作品数量，作者ID：{}", id);
        return authorService.updateAuthorBookCount(id);
    }

    @PutMapping("/{id}/book-count/increment")
    @Operation(summary = "增加作者作品数量", description = "增加作者的作品数量")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> incrementAuthorBookCount(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("增加作者作品数量，作者ID：{}", id);
        return authorService.incrementAuthorBookCount(id);
    }

    @PutMapping("/{id}/book-count/decrement")
    @Operation(summary = "减少作者作品数量", description = "减少作者的作品数量")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> decrementAuthorBookCount(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("减少作者作品数量，作者ID：{}", id);
        return authorService.decrementAuthorBookCount(id);
    }

    @PutMapping("/{id}/borrow-count")
    @Operation(summary = "更新作者总借阅次数", description = "重新统计并更新作者的总借阅次数")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> updateAuthorTotalBorrowCount(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("更新作者总借阅次数，作者ID：{}", id);
        return authorService.updateAuthorTotalBorrowCount(id);
    }

    @PutMapping("/{id}/borrow-count/increment")
    @Operation(summary = "增加作者总借阅次数", description = "增加作者的总借阅次数")
    @PreAuthorize("hasAuthority('library:author:update')")
    public Result<Void> incrementAuthorTotalBorrowCount(
            @Parameter(description = "作者ID", required = true) @PathVariable String id) {
        log.info("增加作者总借阅次数，作者ID：{}", id);
        return authorService.incrementAuthorTotalBorrowCount(id);
    }

    @GetMapping("/check/name/{name}")
    @Operation(summary = "检查作者姓名", description = "检查作者姓名是否已存在")
    @PreAuthorize("hasAuthority('library:author:query')")
    public Result<Boolean> checkAuthorName(
            @Parameter(description = "作者姓名", required = true) @PathVariable String name,
            @Parameter(description = "排除的作者ID") @RequestParam(required = false) String excludeId) {
        log.info("检查作者姓名，姓名：{}，排除ID：{}", name, excludeId);
        boolean exists = authorService.existsByName(name, excludeId);
        return Result.success(!exists);
    }

    @PostMapping("/import")
    @Operation(summary = "导入作者数据", description = "批量导入作者数据")
    @PreAuthorize("hasAuthority('library:author:import')")
    public Result<String> importAuthors(@RequestBody List<AuthorCreateDTO> authors) {
        log.info("导入作者数据，数量：{}", authors.size());
        return authorService.importAuthors(authors);
    }

    @GetMapping("/export")
    @Operation(summary = "导出作者数据", description = "导出作者数据到Excel文件")
    @PreAuthorize("hasAuthority('library:author:export')")
    public Result<String> exportAuthors(@Valid AuthorQuery query) {
        log.info("导出作者数据，查询条件：{}", query);
        return authorService.exportAuthors(query);
    }
}
